# -*- coding: utf-8 -*-
"""
模型配置模块

本模块定义了LLM后端服务的所有模型相关配置，包括：
- Ollama服务配置
- 嵌入模型配置  
- 文本生成参数配置

所有配置项都支持通过环境变量进行覆盖，便于在不同环境中部署。
"""
import os
from typing import Optional


class ModelConfig:
    """
    模型配置类
    
    集中管理所有与模型相关的配置参数，支持从环境变量读取配置值。
    这样设计的好处是：
    1. 配置集中管理，便于维护
    2. 支持环境变量覆盖，适应不同部署环境
    3. 类型注解提供更好的IDE支持
    """
    
    # ==================== Ollama服务配置 ====================
    # Ollama服务的基础URL地址，用于连接到Ollama API服务
    # 默认值指向本地网络中的Ollama服务实例
    OLLAMA_BASE_URL: str = os.getenv("OLLAMA_BASE_URL", "http://10.48.0.81:11434")
    
    # 使用的Ollama模型名称，这里使用DeepSeek R1 32B模型
    # DeepSeek R1是一个高性能的推理优化模型，适合问答任务
    OLLAMA_MODEL: str = os.getenv("OLLAMA_MODEL", "deepseek-r1:32b")
    
    # ==================== 嵌入模型配置 ====================
    # 文本嵌入模型名称，用于将文本转换为向量表示
    # 这里复用了主模型，也可以使用专门的嵌入模型如sentence-transformers
    EMBEDDING_MODEL: str = os.getenv("EMBEDDING_MODEL", "deepseek-r1:32b")
    
    # 嵌入向量的维度大小，影响向量存储空间和检索精度
    # 5120是 deepseek-r1:32b 模型的嵌入维度
    EMBEDDING_DIMENSION: int = int(os.getenv("EMBEDDING_DIMENSION", "5120"))
    
    # ==================== 文本生成配置 ====================
    # 生成温度参数，控制输出的随机性和创造性
    # 0.0 = 完全确定性输出，1.0 = 高随机性输出
    # 0.7是一个平衡值，既保证一定的创造性又不会太随机
    TEMPERATURE: float = float(os.getenv("TEMPERATURE", "0.7"))
    
    # 最大生成token数量，控制单次生成的文本长度上限
    # 2048 tokens大约对应1500-2000个中文字符
    MAX_TOKENS: int = int(os.getenv("MAX_TOKENS", "2048"))
    
    # Top-P采样参数（核采样），控制候选词汇的累积概率阈值
    # 0.9表示选择累积概率达到90%的词汇作为候选集
    # 较小的值会使输出更加集中和一致
    TOP_P: float = float(os.getenv("TOP_P", "0.9"))
    
    # Top-K采样参数，限制每步生成时考虑的候选词汇数量
    # 40表示只考虑概率最高的40个词汇
    # 较小的值会使输出更加确定性
    TOP_K: int = int(os.getenv("TOP_K", "40"))
    
    def validate_config(self) -> bool:
        """
        验证配置的有效性
        
        Returns:
            bool: 配置是否有效
        """
        # 检查必要的配置项
        if not self.OLLAMA_BASE_URL:
            return False
        if not self.OLLAMA_MODEL:
            return False
        if self.EMBEDDING_DIMENSION <= 0:
            return False
        if not (0.0 <= self.TEMPERATURE <= 2.0):
            return False
        if self.MAX_TOKENS <= 0:
            return False
        # 新增：验证采样参数
        if not (0.0 <= self.TOP_P <= 1.0):
            return False
        if self.TOP_K <= 0:
            return False
        return True
    
    def get_config_summary(self) -> dict:
        """
        获取配置摘要信息
        
        Returns:
            dict: 配置摘要字典
        """
        return {
            "ollama_url": self.OLLAMA_BASE_URL,
            "main_model": self.OLLAMA_MODEL,
            "embedding_model": self.EMBEDDING_MODEL,
            "embedding_dim": self.EMBEDDING_DIMENSION,
            "temperature": self.TEMPERATURE,
            "max_tokens": self.MAX_TOKENS,
            # 新增：采样参数
            "top_p": self.TOP_P,
            "top_k": self.TOP_K
        }


# 创建全局配置实例
# 这个实例会在模块导入时创建，其他模块可以直接导入使用
model_config = ModelConfig()